﻿define([
    'dojo/_base/declare',
    'esri/layers/GraphicsLayer',
    'geomap/plugins/arcgisToGeojson',
], function (declare, GraphicsLayer, ArcgisToGeojson) {
    var PointLayer = declare([GraphicsLayer], {
        setData: function (mapView, layer) {
            var me = this;
            if (!mapView) {
                return;
            }
            me.mapView = mapView;
            var mapUtils = mapView.mapUtils;
            me.mapUtils = mapUtils;
            var options = layer.layer || {};
            if (!options.url) {
                return;
            }
            var symbolFieldName = options.symbolFieldName || mapView.getSymbolFieldName();
            me.symbolFieldName = symbolFieldName;
            var spatialReference = null;
            if (options.sr) {
                spatialReference = me.spatialReference;
            }
            var esri = mapView.getEsri();
            var sysObj = {
                esriGeometryPoint: {
                    color: [255, 0, 0, 128],
                    size: 12,
                    angle: 0,
                    xoffset: 0,
                    yoffset: 0,
                    type: 'simplePoint',
                    //type: "esriSMS",
                    //  style: "esriSMSCircle",
                    style: 'circle',
                    outline: {
                        color: [0, 0, 0, 255],
                        width: 1,
                        type: 'esriSLS',
                        style: 'solid',
                        //  style: "esriSLSSolid"
                    },
                },
                esriGeometryPoint_image: {
                    type: 'imagePoint',
                },
                esriGeometryPolyline: {
                    color: [0, 0, 0, 255],
                    width: 1,
                    type: 'simplePolyline',
                    // type: "esriSLS",
                    // style: "esriSLSSolid"
                    style: 'solid',
                },
                esriGeometryPolygon: {
                    color: [255, 0, 0, 20],
                    outline: {
                        color: [255, 0, 0, 255],
                        width: 1,
                        type: 'esriSLS',
                        style: 'solid',
                        // style: "esriSLSSolid"
                    },
                    type: 'simplePolygon',
                    // type: "esriSFS",
                    //style: "esriSFSSolid"
                    style: 'solid',
                },
            };
            me.sysObj = sysObj;
            me.type = {
                simplePoint: 'esriSMS',
                imagePoint: 'esriPMS',
                simplePolyline: 'esriSLS',
                simplePolygon: 'esriSFS',
            };
            me.simpleImage_style = {};
            me.simplePoint_style = {
                esriSMSCircle: 'circle',
                esriSMSCross: 'cross',
                esriSMSDiamond: 'diamond',
                esriSMSSquare: 'square',
                esriSMSX: 'x',
            };
            me.simplePolyline_style = {
                esriSLSSolid: 'solid',
                esriSLSDash: 'dash',
                esriSLSDashDot: 'dashdot',
                esriSLSLongDashDotDot: 'longdashdotdot',
                esriSLSDot: 'dot',
                esriSLSLongDash: 'longdash',
                esriSLSLongDashDot: 'longdashdot',
                esriSLSNull: 'none',
                esriSLSShortDash: 'shortdash',
                esriSLSShortDashDot: 'shortdashdot',
                esriSLSShortDashDotDot: 'shortdashdotdot',
                esriSLSShortDot: 'shortdot',
            };
            me.simplePolygon_style = {
                esriSFSSolid: 'solid',
                esriSFSCross: 'cross',
                esriSFSDiagonal: 'diagonal',
                esriSFSDiagonalCross: 'diagonalCross',
                esriSFSForwardDiagonal: 'forwardDiagonal',
                esriSFSHorizontal: 'horizontal',
                esriSFSNull: 'none',
                esriSFSVertical: 'vertical',
            };

            mapUtils.$.ajax({
                url: options.url,
                success: function (res) {
                    if (typeof res == 'string') {
                        res = JSON.parse(res);
                    }
                    layer._geoJSON = res;
                    //by MHQ 将geojson转换成esriJson
                    let esriJson = ArcgisToGeojson.geojsonToArcGIS(res);
                    //补充esriJson需要的图层类型
                    esriJson = me.getGeometryType(esriJson);

                    var symbol = sysObj[esriJson.geometryType];
                    if (typeof options[symbolFieldName] == 'string') {
                        symbol = options[symbolFieldName];
                        mapUtils.getSymbol(mapView, symbol, function (symbol) {
                            me.callback(esriJson, symbol, layer);
                        });
                    } else {
                        if (!esriJson.geometryType) {
                            console.error('geometryType error');
                            return;
                        }
                        symbol = mapUtils.$.extend(
                            true,
                            sysObj[esriJson.geometryType],
                            options[symbolFieldName]
                        );
                        var sys = mapUtils.createSymbol(mapView, symbol);
                        me.callback(esriJson, sys, layer);
                    }
                },
                error: function (err) {
                    console.log(options.url);
                    console.error('EsriJsonLayer请求json地址报错！');
                },
            });
        },
        getGeometryType: function (esriJson) {
            if (!esriJson.length) {
                console.log('无数据');
                return;
            }
            let geometryType = '';
            let geometry = esriJson[0].geometry;
            if (geometry.x && geometry.y) {
                geometryType = 'esriGeometryPoint';
            } else if (geometry.paths) {
                geometryType = 'esriGeometryPolyline';
            } else if (geometry.rings) {
                geometryType = 'esriGeometryPolygon';
            }
            return { geometryType, features: esriJson };
        },
        coordinateConvert: function (feature, coordinateConvert, geometryType) {
            var me = this;
            var geo = feature.geometry;
            switch (geometryType) {
                case 'esriGeometryPolygon':
                    var rings = geo.rings;
                    for (let i = 0; i < rings.length; i++) {
                        let ring = rings[i];
                        for (let g = 0; g < ring.length; g++) {
                            let obj = me.mapUtils[coordinateConvert]({
                                x: ring[g][0],
                                y: ring[g][1],
                            });
                            ring[g] = [obj.x, obj.y];
                        }
                    }
                    break;
                case 'esriGeometryPolyline':
                    var paths = geo.paths;
                    for (let i = 0; i < paths.length; i++) {
                        let path = paths[i];
                        for (let g = 0; g < path.length; g++) {
                            let obj = me.mapUtils[coordinateConvert]({
                                x: path[g][0],
                                y: path[g][1],
                            });
                            path[g] = [obj.x, obj.y];
                        }
                    }
                    break;
                case 'esriGeometryPoint':
                    let obj = me.mapUtils[coordinateConvert]({ x: geo.x, y: geo.y });
                    feature.geometry.x = obj.x;
                    feature.geometry.y = obj.y;
                    break;
            }
        },
        callback: function (res, symbol, layer) {
            var me = this;
            var options = layer.layer;
            res.features.map(function (feature, index) {
                feature.geometry.spatialReference =
                    feature.spatialReference || res.spatialReference;
                if (feature.symbol) {
                    feature.symbol.type = me.sysObj[res.geometryType]
                        ? me.sysObj[res.geometryType].type
                        : '';
                    if (feature.symbol.style) {
                        feature.symbol.style =
                            me[feature.symbol.type + '_style'][feature.symbol.style];
                    }

                    symbol = me.mapUtils.createSymbol(me.mapView, feature.symbol);
                }
                if (options.coordinateConvert) {
                    me.coordinateConvert(feature, options.coordinateConvert, res.geometryType);
                }

                var graphic = new esri.Graphic(feature);

                graphic.setSymbol(symbol);

                me.add(graphic);
                if (index == res.features.length - 1) {
                    if ($.isFunction(options.callback)) {
                        options.callback(layer);
                    }
                }
            });
        },
        getGraphicLocation: function (mapView, esriEvent) {
            var me = this;
            var location = null;
            var mapUtils = mapView.mapUtils;
            var _geometryType = esriEvent.graphic.geometry.type;
            switch (_geometryType) {
                case mapUtils.Enum.GType.Point:
                    location = me.getPointGraphicLocation(mapView, esriEvent);
                    break;
                case mapUtils.Enum.GType.Polyline:
                    location = me.getPolylineGraphicLocation(mapView, esriEvent);
                    break;
                case mapUtils.Enum.GType.Extent:
                case mapUtils.Enum.GType.Circle:
                case mapUtils.Enum.GType.Polygon:
                    location = me.getPolygonGraphicLocation(mapView, esriEvent);
                    break;
                case mapUtils.Enum.GType.Text:
                    location = me.getTextGraphicLocation(mapView, esriEvent);
                    break;
            }
            return location;
        },
        getPointGraphicLocation: function (mapView, esriEvent) {
            if (!esriEvent || !esriEvent.graphic) {
                return;
            }
            var geometry = esriEvent.graphic.geometry || {};

            var lngFieldName = mapView.getLngFieldName();
            var latFieldName = mapView.getLatFieldName();
            var location = {};
            location[lngFieldName] = geometry.x;
            location[latFieldName] = geometry.y;
            return location;
        },
        getPolylineGraphicLocation: function (mapView, esriEvent) {
            if (!esriEvent || !esriEvent.mapPoint) {
                return;
            }
            var geometry = esriEvent.mapPoint || {};

            var lngFieldName = mapView.getLngFieldName();
            var latFieldName = mapView.getLatFieldName();
            var location = {};
            location[lngFieldName] = geometry.x;
            location[latFieldName] = geometry.y;
            return location;
        },
        getPolygonGraphicLocation: function (mapView, esriEvent) {
            if (!esriEvent || !esriEvent.mapPoint) {
                return;
            }
            var geometry = esriEvent.mapPoint || {};
            var lngFieldName = mapView.getLngFieldName();
            var latFieldName = mapView.getLatFieldName();
            var location = {};
            location[lngFieldName] = geometry.x;
            location[latFieldName] = geometry.y;
            return location;
        },
        getTextGraphicLocation: function (mapView, esriEvent) {
            if (!esriEvent || !esriEvent.graphic) {
                return;
            }
            var geometry = esriEvent.graphic.geometry || {};

            var lngFieldName = mapView.getLngFieldName();
            var latFieldName = mapView.getLatFieldName();
            var location = {};
            location[lngFieldName] = geometry.x;
            location[latFieldName] = geometry.y;
            return location;
        },
    });
    return PointLayer;
});
